﻿#include "log.h"
#include <iostream>
#include <cstdio>
#include <cstdarg>
#include <cstring>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>

logger::logger() : printMethod(screen), path("./log/") {}

void logger::ChangeDev(int method)
{
    printMethod = method;
}

std::string logger::leveltostring(int level)
{
    switch (level)
    {
    case Info:
        return "Info";
    case Debug:
        return "Debug";
    case Warning:
        return "Warning";
    case Error:
        return "Error";
    case Fatal:
        return "Fatal";
    default:
        return "unknown";
    }
}

void logger::printonefile(const std::string &filename, const std::string &logtxt)
{
    std::string file_path = path + filename;
    int fd = open(file_path.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0666);
    if (fd < 0)
    {
        return;
    }
    write(fd, logtxt.c_str(), logtxt.size());
    close(fd);
}

void logger::printclassfile(int level, const std::string &logtxt)
{
    std::string filename = logfile;
    filename += ".";
    filename += leveltostring(level);
    printonefile(filename, logtxt);
}

void logger::printlog(int level, std::string logtxt)
{
    switch (printMethod)
    {
    case screen:
        std::cout << logtxt << std::endl;
        break;
    case onefile:
        printonefile(logfile, logtxt);
        break;
    case classfile:
        printclassfile(level, logtxt);
        break;
    default:
        break;
    }
}

void logger::operator()(int level, const char *format, ...)
{
    time_t t = time(NULL);
    struct tm *ctime = localtime(&t);
    char leftbuffer[SIZE];
    snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d/%d/%d %d:%d:%d]", 
             leveltostring(level).c_str(),
             ctime->tm_year + 1900, ctime->tm_mon + 1,
             ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

    va_list s;
    va_start(s, format);
    char rightbuffer[SIZE];
    vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
    va_end(s);

    char logtxt[SIZE * 2];
    snprintf(logtxt, sizeof(logtxt), "%s tid:%p -- %s\n", 
             leftbuffer, (void *)pthread_self(), rightbuffer);

    printlog(level, logtxt);
}

logger LOG;